#ifndef QMAINCANVAS_H
#define QMAINCANVAS_H

#include <QLabel>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPainter>
#include <QPicture>
#include <QPointF>
#include <QRect>
#include <QtSvg>

#include <cmath>

#include "qcelleditdialog.h"
#include "qmaincore.h"
#include "cell.h"

//! A model viewer.
/*!
  QMainCanvas controls all interations between user and a model.
  It also provides a graphical representstion of the model.
  It has tree view modes: normal, vector field and color field.
  In normal mode model represented on the screen as a set of nodes, edges, areas and their numbers.
  In vector field mode only monitored forces of the model are represented on the screen.
  In color field mode forces directions are represented as filled with color triangles.
  Vector or color field modes switch automatically if one or more forces are chousen to be monitored.
  Nodes are represented as white (ordinary) and gray (frontal) circles.
  Edges are represented as black (ordinary) and magenta (boundary) lines.
  Areas are represented as filled rectangles.
 */
class QMainCanvas : public QLabel
{
    Q_OBJECT

    QMainCore *core; //!< Pointer to the model core.
    CELL cell;       //!< Current calculated model.

    //!< Controls the way of response of the current canvas to mouse events:
    /*!
      \c 00 Cell edit mode.
        Left click and drag changes the whole model position with respect to node under cursor.
        Double click invokes cell edit dialog.
      \c 10 Node edit mode.
        Left click adds a new node.
        If there is an existing node under cursor, left click and drag changes its position.
        Right click toggles node boundary option.
        Middle button toggles node frontal option.
      \c 20 Edge edit mode.
        Left click, drag and release adds a new edge.
      \c 30 Area edit mode.
        Left click, drag and release adds a new area.
        If there is a center of the existing area under cursor, left click and drag changes its position.
      */
    int mode;
    //    switch(mode)
    //    {
    //    case 00://Cell edit mode
    //        break;
    //    case 10://Node edit mode
    //        break;
    //    case 20://Edge edit mode
    //        break;
    //    case 30://Area edit mode
    //        break;
    //    }

    bool showNodeNumber;
    bool showEdgeNumber;
    bool showAreaNumber;
    bool vectorFieldMode;
    bool colorFieldMode;

    /* Temporary variables. Used while creating elements before their adding to the core */
    // Points to draw edge or area before adding in into model
    QPointF p1;
    QPointF p2;

    // Id of the element to be moved. No elements is '-1'
    int id;

public:
    explicit QMainCanvas(QMainCore* _core, QWidget *parent = 0);

protected:
    void paintEvent(QPaintEvent *);

    //! Draws model representation on the screen with painter.
    /*!
      \param painter Painter to draw with.
    */
    void drawModel(QPainter &painter);

    //! Draws model information (cell speed, time and time step) on the screen with painter.
    /*!
      \param painter Painter to draw with.
    */
    void drawInformation(QPainter &painter);

    //! Draws an arrow :).
    /*!
      \param painter Painter to draw with.
      \param p1 Starting point.
      \param p2 Eding point.
      \param angle Arrow angle.
      */
    void drawArrow(QPainter &painter, const QPointF& p1, const QPointF& p2, double angle = M_PI/10);

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

signals:

public slots:

    void setCell(const CELL& _cell);
    void setMode(int _mode);

    void saveSvg(const QString& fileName);

    void setShowNodeNumber(bool _showNodeNumber);
    void setShowEdgeNumber(bool _showEdgeNumber);
    void setShowAreaNumber(bool _showAreaNumber);

    void setVectorFieldMode(bool _vectorFieldMode);
    void setColorFieldMode(bool _colorFieldMode);

    //! Returns rainbow color for the angle. alpha == 0 is red, alpha == M_PI is blue.
    /*!
      \param alpha Angle.
      */
    QColor getColorByAngle(double alpha);
};

#endif // QMAINLABEL_H
